package com.ruiysoft.security.tokenGranter;

import com.ruiysoft.security.authToken.MicroprogramAuthenticationToken;
import org.springframework.security.authentication.AccountStatusException;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.OAuth2Request;
import org.springframework.security.oauth2.provider.OAuth2RequestFactory;
import org.springframework.security.oauth2.provider.TokenRequest;
import org.springframework.security.oauth2.provider.token.AbstractTokenGranter;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;

import java.util.Map;

/**
 * Created by 化增光 on 2018/10/28.
 */
public class MicroprogramCodeTokenGranter extends AbstractTokenGranter {

    private static final String GRANT_TYPE = "microprogram_code";
    private final AuthenticationManager authenticationManager;

    public MicroprogramCodeTokenGranter(AuthenticationManager authenticationManager, AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory) {
        this(authenticationManager, tokenServices, clientDetailsService, requestFactory, GRANT_TYPE);
    }

    protected MicroprogramCodeTokenGranter(AuthenticationManager authenticationManager, AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, String grantType) {
        super(tokenServices, clientDetailsService, requestFactory, grantType);
        this.authenticationManager = authenticationManager;
    }

    protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
        Map parameters = tokenRequest.getRequestParameters();
        String code = (String)parameters.get("code");

        //判断code
        MicroprogramAuthenticationToken userAuth = new MicroprogramAuthenticationToken(code,null);
//        userAuth.setHeadImgUrl(headImgUrl);
//        userAuth.setNickname(nickname);
        userAuth.setDetails(parameters);

        Authentication userAuth1;
        try {
            userAuth1 = this.authenticationManager.authenticate(userAuth);

        } catch (AccountStatusException var8) {
            throw new InvalidGrantException(var8.getMessage());
        } catch (BadCredentialsException var9) {
            throw new InvalidGrantException(var9.getMessage());
        }

        if(userAuth1 != null && userAuth1.isAuthenticated()) {
            OAuth2Request storedOAuth2Request = this.getRequestFactory().createOAuth2Request(client, tokenRequest);
            return new OAuth2Authentication(storedOAuth2Request, userAuth1);
        } else {
            throw new InvalidGrantException("Could not authenticate user: ");
        }
    }
}
